home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1996 #6 / Amiga Plus CD - 1996 - No. 06.iso / pd / netz / dl / main.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  8KB  |  329 lines

  1. /* Copyright (C) 1995, 1996 Zlatko Calusic <maverick@fly.cc.fer.hr>
  2. This file is part of DownLoad, FTP Client
  3.  
  4. The DownLoad is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the Free
  6. Software Foundation.
  7.  
  8. The DownLoad is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11. more details.
  12.  
  13. You should have received a copy of the GNU General Public License along with
  14. the DownLoad source; see the file COPYING.  If not, write to the Free
  15. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17. #include "dl.h"
  18.  
  19. /* Global variables */
  20.  
  21. int logfd, master, control, data, local;            /* file descriptors */
  22.  
  23. int retry, nofatal;                                    /* REST */
  24.  
  25. int foreground, customlog, parsed, input, aborted;    /* flags */
  26. int wildcard, cretry = MAXRETRY, custompass=0, customlogin=0;
  27.  
  28. char url[1024], host[256], path[1024], file[256];
  29. char localhost[256], localaddr[4];                    /* essential data */
  30. char username[16], passwd[256], logfile[256], inputfile[256];
  31. char login[16];
  32.  
  33. char buffer[BUFFER], *matching;
  34.  
  35. struct hostent *hptr;
  36.  
  37. struct sockaddr_in data_in;
  38. int addrlen;
  39.  
  40. fd_set fdset;
  41.  
  42. struct timeval ttimer;
  43.  
  44. struct stat statbuf;
  45.  
  46. extern char *optarg;                                /* getopt's globals */
  47. extern int optind, opterr, optopt;
  48.  
  49. void fperror(char *string)
  50. {
  51.     perror(string);
  52.     fputs("Aborting download ...\n", stderr);
  53.     exit(-1);
  54. }
  55.  
  56. void fatal(char *string)
  57. {
  58.     puts(string);
  59.     exit(-1);
  60. }
  61.  
  62. int getlocalhost(void)
  63. {
  64.     char string[256];
  65. #ifdef AMIGA
  66.     if(strcpy(localhost,getenv("HOSTNAME")))
  67.         return OK;
  68.     return ERROR;
  69. #else
  70.     if (!gethostname(localhost, 256))
  71.     {
  72.         if (!strchr(localhost, '.') && !getdomainname(string, 256) && string[0])
  73.         {
  74.             strcat(localhost, ".");
  75.             strcat(localhost, string);
  76.         }
  77.         return OK;
  78.     }
  79.     else
  80.         return ERROR;
  81. #endif
  82. }
  83.  
  84. void initialize(int argc, char **argv)
  85. {
  86.     char ch, *cptr;
  87.     int printed = 0, usage = 0;
  88.  
  89.     strcpy(login,"anonymous");
  90.  
  91.     while ((ch = getopt(argc, argv, "fl:i:r:n:p:h")) != EOF)
  92.         switch (ch)
  93.         {
  94.             case 'f':
  95.                 foreground++;
  96.                 break;
  97.             case 'l':
  98.                 customlog++;
  99.                 strcpy(logfile, optarg);
  100.                 break;
  101.             case 'i':
  102.                 input++;
  103.                 strcpy(inputfile, optarg);
  104.                 break;
  105.             case 'r':
  106.                 if ((cretry = atoi(optarg)) <= 0)
  107.                 {
  108.                     printf("Retry count invalid, setting to %d.\n", MAXRETRY);
  109.                     cretry = MAXRETRY;
  110.                     printed = 1;
  111.                 }
  112.                 else if (cretry > 500)
  113.                 {
  114.                     puts("Retry count too big, setting to 500.");
  115.                     cretry = 500;
  116.                     printed = 1;
  117.                 }
  118.                 break;
  119.             case 'p':
  120.                 custompass++;
  121.                 strcpy(passwd, optarg);
  122.                 break;
  123.             case 'n':
  124.                 customlogin++;
  125.                 strcpy(login, optarg);
  126.                 break;
  127.             case 'h':
  128.             case '?':
  129.             default:
  130.                 usage++;
  131.                 break;
  132.         }
  133.     if (argc == optind + 1)
  134.         strcpy(url, argv[optind]);
  135.     else if (argc == optind + 2)
  136.     {
  137.         strcpy(url, argv[optind]);
  138.         strcat(url, ":");
  139.         strcat(url, argv[optind + 1]);
  140.     }
  141.     else if (argc != optind || !input || usage)
  142.     {
  143. #ifdef AMIGA
  144.         puts("Usage: dl [-i inputfile] [-r retrycnt] [-n login] [-p passwd] [-h] [URL]\n");
  145. #else
  146.         puts("Usage: dl [-f] [-l logfile] [-i inputfile] [-r retrycnt] [-p passwd] [-h] [URL]\n");
  147. #endif
  148.         puts("Command line switches:\n");
  149. #ifndef AMIGA
  150.         puts("         -f           download in the foreground");
  151.         puts("         -l logfile   custom logfile name (works in the background)");
  152. #endif
  153.         puts("         -i inputfile load URLs from the inputfile");
  154.         puts("         -r retrycnt  retry count (default 50, max 500)");
  155. #ifdef AMIGA
  156.         puts("         -p passwd    custom (anonymous) password");
  157.         puts("         -n login     custom login");
  158. #else
  159.         puts("         -p passwd    custom anonymous password");
  160. #endif
  161.         puts("         -h           this help\n");
  162.         puts("URL specification (wildcards are allowed):\n");
  163.         puts("         hostname:pathname");
  164.         puts("         hostname pathname");
  165.         puts("         ftp://hostname/pathname\n");
  166.         exit(0);
  167.     }
  168.     if (!printed)
  169.         printf("Retry count set to %d%s", cretry, cretry == 50 ? " (default).\n" : ".\n");
  170.     if (foreground && customlog)
  171.         puts("Ignoring -l switch, program is running in the foreground.");
  172.     if (!getlocalhost() || !(hptr = gethostbyname(localhost)))
  173.         fatal("Can't resolve local hostname, exiting ...");
  174.     memcpy(localaddr, hptr->h_addr_list[0], 4);
  175. #ifdef AMIGA
  176.     if(!(cptr=getenv("USER")))
  177.         cptr = "unknown";
  178. #else
  179.     if (!(cptr = cuserid(NULL)))
  180.         cptr = "unknown";
  181. #endif
  182.     strcpy(username, cptr);
  183.     if (!custompass)
  184.     {
  185.         strcpy(passwd, cptr);
  186.         strcat(passwd, "@");
  187.         strcat(passwd, localhost);
  188.     }
  189.  
  190.     printf("Using %s as %s password.\n", passwd, login);
  191.  
  192.     return;
  193. }
  194.  
  195. int main(int argc, char **argv)
  196. {
  197.     printf("%s v%s by %s %s, %s\n", PROGRAM, VERSION, AUTHOR, EMAIL, DATE);
  198. #ifdef AMIGA
  199.     printf("Ported to Amiga by Niksa Franceschi <nfrances@zems.fer.hr>, 24 Jul 1996\n");
  200. #endif
  201.     sleep(1);
  202.     initialize(argc, argv);
  203.     fflush(stdout);
  204. #ifndef AMIGA
  205.     if (!foreground)
  206.     {
  207.         int i = 0;
  208.         pid_t pid;
  209.  
  210.         if (!customlog)
  211.         {
  212. #ifdef AMIGA
  213.             sprintf(logfile, "dl_log.%s", username);
  214. #else
  215.             sprintf(logfile, "/tmp/dl_log.%s", username);
  216. #endif
  217.             while (stat(logfile, &statbuf) == 0) {
  218. #ifdef AMIGA
  219.                 sprintf(logfile, "dl_log.%d", ++i);
  220. #else
  221.                 sprintf(logfile, "dl_log.%s.%d", username, ++i);
  222. #endif
  223.             }
  224.         }
  225.         if ((logfd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
  226.             fatal("Can't open log file, exiting ...");
  227. #ifndef AMIGA
  228.         dup2(logfd, 2);
  229. #endif
  230.         close(logfd);
  231.         fputs("****************************************************************\n", stderr);
  232.         fprintf(stderr, "Log file generated by %s v%s\n", PROGRAM, VERSION);
  233.         fprintf(stderr, "Send bug reports to %s %s\n", AUTHOR, EMAIL);
  234. #ifdef AMIGA
  235.         fprintf(stderr, "Ported  to Amiga by Nick <nfrances@zems.fer.hr>\n");
  236. #endif
  237.         fputs("****************************************************************\n", stderr);
  238.         printf("Log file is %s\n", logfile);
  239.         signal(SIGCLD, SIG_IGN);
  240.         switch ((pid = fork()))
  241.         {
  242.             case -1:
  243.                 fatal("Fork failed, try running in the foreground ...");
  244.             case 0:
  245.                 sleep(2);
  246.                 setsid();
  247.                 break;
  248.             default:
  249.                 printf("Continuing in the background (pid %d) ...", (int) pid);
  250.                 fflush(stdout);
  251.                 sleep(1);
  252.                 puts("\n");
  253.                 exit(0);
  254.         }
  255.     }
  256.     else
  257.         dup2(1, 2);
  258. #endif
  259.     if (!input)
  260.         download();
  261.     else
  262.     {
  263.         FILE *inputfp;
  264.  
  265.         if (!(inputfp = fopen(inputfile, "r")))
  266.         {
  267.             fputs("Can't open input file, exiting ...\n", stderr);
  268.             exit(-1);
  269.         }
  270.         if (argc == optind + 1)
  271.             download();
  272.         while (fgets(url, 256, inputfp))
  273.         {
  274.             char *cptr;
  275.  
  276.             if ((cptr = strchr(url, '\n')))
  277.                 *cptr = 0;
  278.             download();
  279.         }
  280.         fclose(inputfp);
  281.     }
  282.     exit(0);
  283. }
  284.  
  285. int download(void)
  286. {
  287.     char *current;
  288.  
  289.     aborted = parsed = wildcard = 0;
  290.     current = NULL;
  291.     fprintf(stderr, "\nDOWNLOAD -> [%s]\n", url);
  292.     for (retry = 1; retry <= cretry; retry++)
  293.     {
  294.         if (aborted)
  295.             return ERROR;
  296.         if (!parsed && !parse())
  297.         {
  298.             fputs("Error parsing hostname and/or pathname, aborting ...\n", stderr);
  299.             return ERROR;
  300.         }
  301.         sleep(5);
  302.         fputc('\n', stderr);
  303.         if (!establish_connection())
  304.             continue;
  305.         if (!ftprequest("USER %s\r\n", login) || !ftprequest("PASS %s\r\n", passwd))
  306.             continue;
  307.         if (*path)
  308.             if (!ftprequest("CWD %s\r\n", path))
  309.                 continue;
  310.         if (!wildcard && (strchr(file, '*') || strchr(file, '?') || strchr(file, '[')) && !get_list())
  311.             continue;
  312.         if (!ftprequest("TYPE I\r\n", NULL))
  313.             continue;
  314. next_file:
  315.         if (!retrieve_file())
  316.             continue;
  317.         if (wildcard && (current = strtok(NULL, "\r")))
  318.         {
  319.             strcpy(file, current);
  320.             retry = 1;
  321.             goto next_file;
  322.         }
  323.         ftprequest("QUIT\r\n", NULL);
  324.         return OK;
  325.     }
  326.     fprintf(stderr, "Maximum retry count reached (%d), aborting ...\n", cretry);
  327.     return ERROR;
  328. }
  329.